package com.ljcalc.business.components;

import java.io.IOException;
import java.sql.Date;
import java.util.*;

import com.ljcalc.business.components.fetchers.HistoryResultFetcher;
import com.ljcalc.business.components.requests.HistoryResultRequest;
import com.ljcalc.business.components.requests.SSLHistoryResultRequest;

/**
 * This is Comment
 * SSL stands for svenska spel lotto
 * @author SELuoc
 *
 */
public class SSLHistoryResultsAnalyzer extends HistoryResultsAnalyzer {

	//ONSDAG start
	private int onsStartYear = 1998;
	private int onsStartWeek = 40;
	
	//lordag start
	private int lorStartYear = 1980;
	private int lorStartWeek = 36;
	
	private static SSLHistoryResultsAnalyzer instance = null;

	private int currentyear = 0;
	private int currentweek = 0;
	private int currenttype = 0;
	
	

	
	
	private SSLHistoryResultsAnalyzer(){
		CAC_NUMBER = 38;
		SUB_COMB_QUANTITY = 21;
		MAX_NUMBER = 35;
		COMB_LENGTH = 7;
		String tc_tolerance = LJCalcProperties.getInstance().getProperty(
		"TIME_CONSECUTIVE_TOLERANCE");
		if (tc_tolerance != null) {
			TIME_CONSECUTIVE_TOLERANCE = Long.valueOf(tc_tolerance).longValue();
		}
		
		resultMap = new HashMap<String,Combination>();
		GregorianCalendar d = new GregorianCalendar();
		d.setTime(new Date(System.currentTimeMillis()));
		
		int dayOfWeek = d.get(Calendar.DAY_OF_WEEK);
		currentyear = d.get(Calendar.YEAR);
		currentweek = d.get(Calendar.WEEK_OF_YEAR);
		
		if(dayOfWeek>=Calendar.SUNDAY&&dayOfWeek<Calendar.THURSDAY){
			currenttype = SSLHistoryResultRequest.LORDAG_TYPE;

			if(currentweek==0){
				currentyear = currentyear-1;
				d.set(Calendar.YEAR, this.currentyear);
				currentweek = d.get(Calendar.WEEK_OF_YEAR);
			}
		}else{
			currenttype = SSLHistoryResultRequest.ONSDAG_TYPE;
		}		
		
		System.out.println(new Date(System.currentTimeMillis()) + ":"+ "Initializing the History Results");
		initHistoryResults();
		
		System.out.println(new Date(System.currentTimeMillis()) + ":"+ "Sorting the result maps");
		resultMap = sortResultMap(resultMap);
		MINMAX_DIFF_TOLERANCE = (resultMap.size()/10);
		getHistorySubCombinationStat();
		
		minMaxDiffStatList = getHistoryMaxMinDiffStat();
		minMaxMidDiffStatList = getHistoryMaxMinMidDiffStat();

		
	}
	
	public static SSLHistoryResultsAnalyzer getInstance(){
		if(instance==null){
			instance = new SSLHistoryResultsAnalyzer();
		}
		return instance;
	}
	

	


	/**
	 * 
	 * @param theindex should be the position of the number in the combination
	 * 			the first one is 0, the last one is 6
	 * @return
	 */
	public List<Integer> getNumberTimeConsecutiveStat(int theindex){

		
		SSLHistoryResultRequest hrr = new SSLHistoryResultRequest(SSLHistoryResultRequest.LORDAG_TYPE, lorStartYear, lorStartWeek);

		List<Combination> firstResults = getResult(hrr.getType(), hrr.getYear(), hrr.getRound());
		List<Integer> retList = getNumberTimeConsecutiveStatSuper(theindex,hrr, firstResults);

		return retList;
	}


	


	public boolean initHistoryResults(){

		
		//from current date get the result type, lordag or onsdag, week and year
		
		//check the local files about the history result until current result type
		theInstance = SSLResultHistories.getInstance();
		//get the latest date from the result, the date information contains year and week and result type
		HistoryResultRequest lastResultRequest = theInstance.getLatestResultInRequest();
		
		//if there is no data about the result
		if(lastResultRequest==null){
			lastResultRequest = new SSLHistoryResultRequest(SSLHistoryResultRequest.LORDAG_TYPE, lorStartYear, lorStartWeek);
		}
		
		return superInit(theInstance, lastResultRequest);
	}
	
	/*
	 * from the 
	 */
	public HistoryResultRequest getNextResultRequest(HistoryResultRequest r) {
		int year = r.getYear();
		int week = r.getRound();
		int type = r.getType();
		
		GregorianCalendar d = new GregorianCalendar();

		d.set(Calendar.YEAR, year);
		
		
		if(type==SSLHistoryResultRequest.ONSDAG_TYPE){
			type = SSLHistoryResultRequest.LORDAG_TYPE;
		}else if(type == SSLHistoryResultRequest.LORDAG_TYPE){
			
			if(year>onsStartYear||(year==onsStartYear&&week>=(onsStartWeek-1))){
				type = SSLHistoryResultRequest.ONSDAG_TYPE;
			}else{
				type = SSLHistoryResultRequest.LORDAG_TYPE;
			}
			
			
			int wd = d.getActualMaximum(Calendar.WEEK_OF_YEAR);
			if(week == wd){
				week = 1;
				year++;
			}else{
				week++;
			}
		
		}
		
		return new SSLHistoryResultRequest(type, year, week);

	}

	/*
	 * check the result request is valied
	 */
	public boolean isValidRequest(HistoryResultRequest lastResultRequest) {

		int year = lastResultRequest.getYear();
		int week = lastResultRequest.getRound();
		int type = 0;
		if(lastResultRequest.getType()==SSLHistoryResultRequest.ONSDAG_TYPE){
			type = Calendar.WEDNESDAY;
		}else if(lastResultRequest.getType()==SSLHistoryResultRequest.LORDAG_TYPE){
			type = Calendar.SATURDAY;
		}
		GregorianCalendar d = new GregorianCalendar();
		
		//year can not exceed the current year number
		if(year>this.currentyear){
			return false;
		}
		
		//week number can not exceed the number of weeks of the year
		d.set(Calendar.YEAR, year);
		if(week>d.getActualMaximum(Calendar.WEEK_OF_YEAR)){
			return false;
		}		
		//if the year is the same as the current year, the week number can not exceed the present week number
		if(year==this.currentyear&&week>this.currentweek){
			return false;
		}
		
		//if the week number is the same as the precent week number, the type can not be larger than the day of the week.
		d.setTime(new Date(System.currentTimeMillis()));
		if(year==this.currentyear&&week==this.currentweek&&type>d.get(Calendar.DAY_OF_WEEK)){
			return false;
		}
		
		return true;
	}

	
	public List<Combination> getCurrentDateResult(){
		return getResult(currenttype, currentyear, currentweek);
	}






	

}
